﻿using System;
using System.Collections.Generic;
using Alone.GameObjects;
using Alone.GameObjects.Enemy;
using Microsoft.Xna.Framework;

namespace Alone.EnemyStates
{
    /// <summary>
    /// Class FleeingState
    /// </summary>
	class FleeingState : EnemyState, IEnemyState
	{
		float fleeingSpeed = 15f;
		Matrix rotationMatrix;
		Vector3 movementVelocity;

        /// <summary>
        /// Initializes a new instance of the <see cref="FleeingState"/> class.
        /// </summary>
		public FleeingState()
			: base()
		{ }

		#region IEnemyState Members

		/// <summary>
		/// Does the AI.
		/// </summary>
		/// <param name="enemies">The enemies.</param>
		/// <param name="players">The players.</param>
		public override void doAI(Enemy enemy, List<Enemy> enemies, List<BasePlayer> players)
		{
			BasePlayer player = players[0];
			float distance = float.MaxValue;

            enemy.AnimationController.Speed = new Random().Next(3, 4);
			movementVelocity = new Vector3(0,0,fleeingSpeed);

			foreach (BasePlayer p in players)
			{
				float tempDist = Vector3.Distance(enemy.Position, p.Position);
				if (tempDist < distance)
				{
					distance = tempDist;
					player = p;
				}
			}

			enemy.Rotation.Y = TurnAwayFrom(enemy.Position, player.Position, enemy.Rotation.Y, 10f);

			rotationMatrix = Matrix.CreateRotationY(enemy.Rotation.Y);
			movementVelocity = Vector3.Transform(movementVelocity, rotationMatrix);
			enemy.Position += movementVelocity;

			if (!isOnPlane(enemy.Position))
			{
                // Turn when hitting edge of heightmap
				enemy.Rotation.Y = TurnToFace(enemy.Position, player.Position, enemy.Rotation.Y, 1f);
			}

            enemy.Position.X = MathHelper.Clamp(enemy.Position.X, -3400, 3400);
            enemy.Position.Z = MathHelper.Clamp(enemy.Position.Z, -3400, 3400);
		}

		/// <summary>
		/// Evaluates each enemies fuzzy value using this state.
		/// The higher the value is, the more likely it is that this state is the best one.
		/// </summary>
		/// <param name="enemy">The enemy.</param>
		/// <param name="enemies">The enemies.</param>
		/// <param name="players">The players.</param>
		/// <returns></returns>
		public override float evaluate(Enemy enemy, List<Enemy> enemies, BasePlayer player)
		{
			float fuzzyValue;
			bool noFriendsNearby = true;

			fuzzyValue = isNearPlayer(enemy.Position, player.Position);
			fuzzyValue -= isVeryNearPlayer(enemy.Position, player.Position);

			foreach (Enemy friend in enemies)
			{
				if (enemy != friend)
				{
					if (isNearFriend(enemy.Position, friend.Position) > 0)
					{
						noFriendsNearby = false;
					}
				}
			}

			if (noFriendsNearby)
			{
                //If this enemy is alone, He is more likely to RUUUN
				fuzzyValue += 0.001f;
			}
			return fuzzyValue;
		}

		#endregion
	}
}
